<template>
  <div class="file-preview-panel fixed">
    <div class="preview-header">
      <div class="preview-title">
        <svg class="preview-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
                d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
                d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"/>
        </svg>
        文件预览
      </div>
      <button class="close-button" @click="$emit('close')">
        <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
        </svg>
      </button>
    </div>

    <div class="preview-content">
      <div v-if="loading" class="loading-state">
        <div class="spinner"></div>
        <span>加载中...</span>
      </div>

      <div v-else-if="error" class="error-state">
        <svg class="error-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
                d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.99-.833-2.76 0L4.054 16.5c-.77.833.192 2.5 1.732 2.5z"/>
        </svg>
        <p>{{ error }}</p>
      </div>

      <div v-else-if="fileContent" class="preview-body">
        <!-- 文件信息 -->
        <div class="file-info">
          <div class="file-info-item">
            <span class="label">文件名:</span>
            <span class="value">{{ currentFile.filename }}</span>
          </div>
          <div class="file-info-item">
            <span class="label">大小:</span>
            <span class="value">{{ formatFileSize(currentFile.size) }}</span>
          </div>
          <div class="file-info-item">
            <span class="label">类型:</span>
            <span class="value">{{ getFileType(currentFile.filename) }}</span>
          </div>
        </div>

        <!-- 预览内容 -->
        <div class="preview-container">
          <!-- 图片预览 -->
          <div v-if="isImage" class="image-preview">
            <img :src="fileUrl" :alt="currentFile.filename" @error="handleImageError" />
          </div>

          <!-- 文本预览 -->
          <div v-else-if="isText" class="text-preview">
            <pre><code>{{ fileContent }}</code></pre>
          </div>

          <!-- PDF预览 -->
          <div v-else-if="isPdf" class="pdf-preview">
            <embed :src="fileUrl" type="application/pdf" width="100%" height="600px" />
          </div>

          <!-- 音频预览 -->
          <div v-else-if="isAudio" class="audio-preview">
            <audio controls :src="fileUrl">
              您的浏览器不支持音频播放
            </audio>
          </div>

          <!-- 视频预览 -->
          <div v-else-if="isVideo" class="video-preview">
            <video controls :src="fileUrl">
              您的浏览器不支持视频播放
            </video>
          </div>

          <!-- 不支持的文件类型 -->
          <div v-else class="unsupported-preview">
            <svg class="unsupported-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" 
                    d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
            </svg>
            <p>此文件类型暂不支持预览</p>
            <button class="download-button" @click="downloadFile">下载文件</button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch } from 'vue'

// Props
const props = defineProps({
  file: {
    type: Object,
    default: null
  }
})

// Emits
defineEmits(['close'])

// Reactive data
const loading = ref(false)
const error = ref('')
const fileContent = ref('')
const currentFile = ref(null)

// Computed properties
const fileUrl = computed(() => {
  return currentFile.value ? `/api/lan-share/preview/${encodeURIComponent(currentFile.value.filename)}` : ''
})

const downloadUrl = computed(() => {
  return currentFile.value ? `/api/lan-share/${encodeURIComponent(currentFile.value.filename)}` : ''
})

const isImage = computed(() => {
  if (!currentFile.value) return false
  const ext = getFileExtension(currentFile.value.filename).toLowerCase()
  return ['jpg', 'jpeg', 'png', 'gif', 'webp', 'svg', 'bmp'].includes(ext)
})

const isText = computed(() => {
  if (!currentFile.value) return false
  const ext = getFileExtension(currentFile.value.filename).toLowerCase()
  return ['txt', 'json', 'js', 'ts', 'vue', 'html', 'css', 'md', 'xml', 'csv', 'log'].includes(ext)
})

const isPdf = computed(() => {
  if (!currentFile.value) return false
  const ext = getFileExtension(currentFile.value.filename).toLowerCase()
  return ext === 'pdf'
})

const isAudio = computed(() => {
  if (!currentFile.value) return false
  const ext = getFileExtension(currentFile.value.filename).toLowerCase()
  return ['mp3', 'wav', 'ogg', 'm4a', 'aac'].includes(ext)
})

const isVideo = computed(() => {
  if (!currentFile.value) return false
  const ext = getFileExtension(currentFile.value.filename).toLowerCase()
  return ['mp4', 'webm', 'ogg', 'avi', 'mov'].includes(ext)
})

// Methods
const getFileExtension = (filename) => {
  return filename.split('.').pop() || ''
}

const getFileType = (filename) => {
  const ext = getFileExtension(filename).toLowerCase()
  const typeMap = {
    // 图片
    jpg: '图片', jpeg: '图片', png: '图片', gif: '图片', webp: '图片', svg: '图片', bmp: '图片',
    // 文档
    pdf: 'PDF文档', doc: 'Word文档', docx: 'Word文档', txt: '文本文件',
    // 代码
    js: 'JavaScript', ts: 'TypeScript', vue: 'Vue组件', html: 'HTML文件', css: 'CSS文件',
    json: 'JSON文件', xml: 'XML文件', md: 'Markdown文件',
    // 音频
    mp3: '音频文件', wav: '音频文件', ogg: '音频文件', m4a: '音频文件', aac: '音频文件',
    // 视频
    mp4: '视频文件', webm: '视频文件', avi: '视频文件', mov: '视频文件',
    // 压缩包
    zip: '压缩包', rar: '压缩包', '7z': '压缩包', tar: '压缩包'
  }
  return typeMap[ext] || '未知类型'
}

const formatFileSize = (bytes) => {
  if (bytes === 0) return '0 Bytes'
  const k = 1024
  const sizes = ['Bytes', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

const loadFileContent = async () => {
  if (!currentFile.value) return

  loading.value = true
  error.value = ''
  fileContent.value = ''

  try {
    if (isText.value) {
      // 加载文本内容
      const response = await fetch(fileUrl.value)
      if (!response.ok) throw new Error('加载文件失败')
      fileContent.value = await response.text()
    } else {
      // 对于其他类型，只设置 URL
      fileContent.value = 'loaded'
    }
  } catch (err) {
    console.error('Load file error:', err)
    error.value = '加载文件失败: ' + err.message
  } finally {
    loading.value = false
  }
}

const handleImageError = () => {
  error.value = '图片加载失败'
}

const downloadFile = () => {
  const link = document.createElement('a')
  link.href = downloadUrl.value
  link.download = currentFile.value.filename
  link.click()
}

// Watch for file changes
watch(() => props.file, (newFile) => {
  if (newFile) {
    currentFile.value = newFile
    loadFileContent()
  }
}, { immediate: true })
</script>

<style scoped>
.file-preview-panel {
  width: 760px;
  background: white;
  border-radius: 16px;
  border: 1px solid rgba(0, 0, 0, 0.06);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.04);
  height: calc(100vh - 40px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  /* position: sticky; */
  top: 20px;
  min-height: 100vh;
}

.preview-header {
  padding: 20px 24px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: rgba(0, 0, 0, 0.02);
}

.preview-title {
  font-size: 18px;
  font-weight: 600;
  color: #1d1d1f;
  display: flex;
  align-items: center;
}

.preview-icon {
  width: 18px;
  height: 18px;
  margin-right: 8px;
  color: #6e6e73;
}

.close-button {
  background: rgba(142, 142, 147, 0.1);
  color: #8e8e93;
  border: none;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s ease;
}

.close-button:hover {
  background: rgba(142, 142, 147, 0.2);
  transform: scale(1.05);
}

.close-button svg {
  width: 16px;
  height: 16px;
}

.preview-content {
  flex: 1;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.loading-state, .error-state {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #8e8e93;
  gap: 12px;
}

.spinner {
  width: 24px;
  height: 24px;
  border: 2px solid #f3f3f3;
  border-top: 2px solid #007aff;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.error-icon {
  width: 48px;
  height: 48px;
  color: #ff3b30;
}

.preview-body {
  flex: 1;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.file-info {
  padding: 20px 24px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
  background: rgba(0, 0, 0, 0.01);
}

.file-info-item {
  display: flex;
  margin-bottom: 8px;
}

.file-info-item:last-child {
  margin-bottom: 0;
}

.label {
  font-weight: 600;
  color: #6e6e73;
  min-width: 60px;
  font-size: 13px;
}

.value {
  color: #1d1d1f;
  font-size: 13px;
  word-break: break-all;
}

.preview-container {
  flex: 1;
  overflow: auto;
  padding: 20px 24px;
}

.image-preview img {
  max-width: 100%;
  height: auto;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.text-preview {
  background: #f8f9fa;
  border-radius: 8px;
  padding: 16px;
  overflow: auto;
  max-height: 500px;
}

.text-preview pre {
  margin: 0;
  font-family: 'Monaco', 'Menlo', monospace;
  font-size: 12px;
  line-height: 1.5;
  color: #1d1d1f;
  white-space: pre-wrap;
  word-wrap: break-word;
}

.pdf-preview, .audio-preview, .video-preview {
  text-align: center;
}

.audio-preview audio, .video-preview video {
  max-width: 100%;
  border-radius: 8px;
}

.unsupported-preview {
  text-align: center;
  color: #8e8e93;
  padding: 40px 20px;
}

.unsupported-icon {
  width: 64px;
  height: 64px;
  margin-bottom: 16px;
  color: #c7c7cc;
}

.download-button {
  background: #007aff;
  color: white;
  border: none;
  padding: 10px 20px;
  border-radius: 8px;
  font-weight: 500;
  cursor: pointer;
  margin-top: 16px;
  transition: all 0.2s ease;
}

.download-button:hover {
  background: #0056cc;
  transform: translateY(-1px);
}
</style> 